# -*- coding: utf-8 -*-
import logging
import random
import string
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from test.utils.WaitUntil import WaitUntil
from utils.mysql_select import MysqlSelect
from selenium.webdriver.common.keys import Keys
from test.utils.DirAndTime import *
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.ie.options import Options as IEOptions
from selenium.webdriver.edge.options import Options as EdgeOptions
# from utils.mysql_select import MysqlSelect


driver = None
wait_util = None
driver: webdriver.Chrome
wait_util: WaitUntil(driver)

GRID_URL = 'http://localhost:8888/wd/hub'
DEFAULT_BROWSER_VERSION = None
DEFAULT_PLATFORM = None


# 实现元素查找功能（替代原 ele_object）
def get_element(driver, by, locator):
    if by == "id":
        return driver.find_element(By.ID, locator)
    elif by == "name":
        return driver.find_element(By.NAME, locator)
    elif by == "class":
        return driver.find_element(By.CLASS_NAME, locator)
    elif by == "xpath":
        return driver.find_element(By.XPATH, locator)
    elif by == "link_text":
        return driver.find_element(By.LINK_TEXT, locator)
    elif by == "partial_link_text":
        return driver.find_element(By.PARTIAL_LINK_TEXT, locator)
    elif by == "tag_name":
        return driver.find_element(By.TAG_NAME, locator)
    elif by == "css_selector":
        return driver.find_element(By.CSS_SELECTOR, locator)
    else:
        raise ValueError(f"Unsupported locator type: {by}")


# 打开浏览器
# def open_browser(browser):
#     global driver, wait_util
#     try:
#         if browser.lower() == 'ie':
#             # driver = webdriver.Ie(iePath)
#             driver = webdriver.Ie()
#         elif browser.lower() == 'chrome':
#             # driver = webdriver.Chrome(chromePath)
#             driver = webdriver.Chrome()
#         elif browser.lower() == 'edge':
#             driver = webdriver.Edge()
#         else:
#             # driver = webdriver.Firefox(fireFox)
#             driver = webdriver.Firefox()
#     except Exception as e:
#         raise e
#     else:
#         wait_util = WaitUntil(driver)  # driver 创建之后， 创建等待类实例对象
def open_browser(browser, browser_version=DEFAULT_BROWSER_VERSION, platform_name=DEFAULT_PLATFORM):
    global driver, wait_util
    try:
        # 根据浏览器类型创建选项
        if browser.lower() == 'ie':
            options = IEOptions()
            options.set_capability('browserName', 'internet explorer')
        elif browser.lower() == 'chrome':
            options = ChromeOptions()
            options.set_capability('browserName', 'chrome')
        elif browser.lower() == 'edge':
            options = EdgeOptions()
            options.set_capability('browserName', 'MicrosoftEdge')
        elif browser.lower() == 'firefox':
            options = FirefoxOptions()
            options.set_capability('browserName', 'firefox')
        else:
            raise ValueError(f"不支持的浏览器: {browser}")

        # 仅当提供非空版本时才设置browserVersion
        if browser_version:
            options.set_capability('browserVersion', browser_version)

        # 仅当提供有效平台时才设置platformName
        if platform_name and platform_name != 'ANY':
            options.set_capability('platformName', platform_name)

        # 设置通用能力
        options.set_capability('se:javascriptEnabled', True)

        # 连接到Selenium Grid
        driver = webdriver.Remote(
            command_executor=GRID_URL,
            options=options
        )

    except Exception as e:
        raise e
    else:
        wait_util = WaitUntil(driver)  # driver 创建之后， 创建等待类实例对象

# 浏览器窗口最大化
def maximize_browser():
    try:
        driver.maximize_window()
    except Exception as e:
        raise e

# # 浏览器窗口最大化
# def maximize_browser():
#     try:
#         driver.maximize_window()
#     except Exception as e:
#         raise e


# 加载网址
def load_url(url):
    """
    :param url: 地址
    :return:
    """
    try:
        driver.get(url)
    except Exception as e:
        raise e


# todo 切换页面
def window_handles():
    driver.switch_to.window(driver.window_handles[-1])


# 强制等待
def sleep(sleep_seconds):
    try:
        import time
        time.sleep(sleep_seconds)
    except Exception as e:
        raise e


# 清空输入的内容
def clear(by, locator):
    try:
        get_element(driver, by, locator).clear()
    except Exception as e:
        raise e


# 输入框中输入内容
def input_value(by, locator, value):
    try:
        element = get_element(driver, by, locator)
        # element.click()
        element.send_keys(value)
    except Exception as e:
        raise e


def execute_script():
    import time
    # 方法一：坐标法
    driver.execute_script('window.scrollTo(0,500)')  # 横坐标不变，纵坐标 滚动到1000像素点
    time.sleep(2)  # 等待一段时间，方便查看滚动的效果


def input_random_str_value(by, locator, value, length):
    """
    输入拼接上的随机字符串的内容
    :param by: 定位方式
    :param locator: 定位元素值
    :param value: 输入内容
    :param length: 拼接随机字符串长度
    :return:
    """
    rand_str = ''.join(random.choices(string.ascii_letters + string.digits, k=length))
    full_value = value + rand_str
    try:
        element = get_element(driver, by, locator)
        element.send_keys(full_value)
    except Exception as e:
        raise e


def input_random_int_value(by, locator, value, start, end):
    """
    拼接上的范围内的数字
    :param by: 定位方式
    :param locator: 定位元素值
    :param value: 输入内容
    :param start: 开始范围
    :param end: 结束范围
    :return:
    """
    rand_num = random.randint(start, end)
    full_value = value + str(rand_num)
    try:
        element = get_element(driver, by, locator)
        element.send_keys(full_value)
    except Exception as e:
        raise e


# 点击操作
def click_btn(by, locator):
    try:
        get_element(driver, by, locator).click()
    except Exception as e:
        raise e


# 断言页面的title
def assert_title(title_str):
    try:
        assert title_str in driver.title, "%s not found in title!" % title_str
    except AssertionError as e:
        raise AssertionError(e)
    except Exception as e:
        raise e


# 断言目标字符串是否包含在页面源码中
def assert_string_in_page_source(assert_string):
    try:
        assert assert_string in driver.page_source, "%s not found in page source!" % assert_string
    except AssertionError as e:
        raise AssertionError(e)
    except Exception as e:
        raise e


# 获取当前页面的title
def get_title():
    try:
        return driver.title
    except Exception as e:
        raise e


# 获取页面源码
def get_page_source():
    try:
        return driver.page_source
    except Exception as e:
        raise e


# 切换到frame里面
def switch_to_frame(by, locator):
    try:
        driver.switch_to.frame(get_element(driver, by, locator))
    except Exception as e:
        raise e


# 跳到默认的frame
def switch_to_default():
    try:
        driver.switch_to.default_content()
    except Exception as e:
        raise e


# 屏幕截图
def save_screen_shot():
    picture_name = DirAndTime.create_picture_path() + '\\' + DirAndTime.get_current_time() + '.png'
    try:
        driver.get_screenshot_as_file(picture_name)
    except Exception as e:
        raise e
    else:
        return picture_name


def wait_presence_of_element_located(by, locator):
    """
    显示等待页面元素出现在DOM中，不一定可见
    :param by:
    :param locator:
    :return:
    """
    wait_util.presence_of_element_located(by, locator)


def wait_frame_to_be_available_and_switch_to_it(by, locator):
    """
    检查frame是否存在，存在就切换到frame中
    :param by:
    :param locator:
    :return:
    """
    wait_util.frame_to_be_available_and_switch_to_it(by, locator)


def wait_visibility_of_element_located(by, locator):
    """
    显示等待页面元素出现在DOM中，并且可见
    :param by:
    :param locator:
    :return:
    """
    wait_util.visibility_of_element_located(by, locator)


# 关闭浏览器
def quit_browser():
    try:
        driver.quit()
    except Exception as e:
        raise e

# 断言文本相等
def assertdy(cz, loc, text1, *args):
    if cz == 'xpath':
        textdy = driver.find_element(By.XPATH, loc).text
        assert textdy == text1, f'断言失败：{textdy} 不等于 {text1}'
        print(f'实际获取的文本：{textdy}')
        print(f'预期获取的文本：{text1}')

# 断言在文本中
def assertdy_in(cz, loc, text1, *args):
    if cz == 'xpath':
        textdy = driver.find_element(By.XPATH, loc).text
        assert text1 in textdy, f'断言失败：{textdy} 不等于 {text1}'
        print(f'实际获取的文本：{textdy}')
        print(f'预期获取的文本：{text1}')



def assert_mysql_first_value(table, key_data=None, value_data=None, param=None, assert_value=None):
    """
    断言单条数据, 获取对应的字段的值
    :param table: 表名
    :param key_data: 判断的字段名用[]传入，[字段1,字段2,字段3]
    :param value_data: 判断的字段值用[]传入，[值1,值2,值3]
    :param param: 你所要获取到字段的条件
    :param assert_value: 要断言的值
    :return:
    """
    if key_data:
        # key_data = [f'{key_data}']
        key_data = key_data

    if value_data:
        # value_data = [f'{value_data}']
        value_data = value_data
    result = MysqlSelect().mysql_select_first(table, key_data, value_data, param)
    assert assert_value == result, f'预期结果是：{assert_value},实际结果是：{result},断言不通过'
    logging.info(f'预期结果是：{assert_value},实际结果是：{result},断言通过')


def assert_mysql_length(table, key_data=None, value_data=None, assert_value=None):
    """
    断言获取到符合条件数据的数量
    :param table: 表名
    :param key_data: 判断的字段名用[]传入，[字段1,字段2,字段3]
    :param value_data: 判断的字段值用[]传入，[值1,值2,值3]
    :param assert_value: 预期长度
    :return:
    """
    if key_data:
        # key_data = [f'{key_data}']
        key_data = key_data

    if value_data:
        # value_data = [f'{value_data}']
        value_data = value_data

    result = MysqlSelect().mysql_length(table, key_data, value_data)
    assert assert_value == result, f'预期存在数据数量：{assert_value},实际存在数据数量：{result},断言不通过'
    logging.info(f'预期存在数据数量：{assert_value},实际存在数据数量：{result},断言通过')


if __name__ == '__main__':
    from time import sleep

    # open_browser('firefox')
    # load_url('http://www.baidu.com')
    # input_value('id', 'kw', 'python')
    # clear('id', 'kw')
    # input_value('id', 'kw', 'python')
    # click_btn('id', 'su')
    # sleep(3)
    # title = get_title()
    # print(title)
    # assert_title('python')
    # assert_string_in_page_source('python')
    # # ctrl_v('python')
    # sleep(3)
    # quite_browser()

    # assert_mysql_first_value('y_user', "username", "admin", 'pwd', 'ebcbf97ec1d80c0388d39bf508039baa')
    assert_mysql_first_value('area', ["name", "sort"], ['上地', '2'], 'atype', 2)
    # assert_mysql_length('y_user', "username", "admin", 1)
    assert_mysql_length('area', ["name", "sort"], ["上地", '2'], 1)
